package com.gcloud.mesh.monitor.timer;

import java.math.BigDecimal;
import java.security.SecureRandom;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import org.jeecg.common.constant.DictCode;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.modules.system.mapper.SysDictMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.gcloud.framework.db.PageResult;
import com.gcloud.mesh.asset.service.IAssetService;
import com.gcloud.mesh.asset.service.ICloudResourceService;
import com.gcloud.mesh.dcs.service.AppService;
import com.gcloud.mesh.header.enums.MonitorMeter;
import com.gcloud.mesh.header.msg.asset.ListDatacenterMsg;
import com.gcloud.mesh.header.msg.asset.PageCloudResourceMsg;
import com.gcloud.mesh.header.msg.dcs.PageAppMsg;
import com.gcloud.mesh.header.vo.asset.CloudResourceItemVo;
import com.gcloud.mesh.header.vo.asset.DatacenterItemVo;
import com.gcloud.mesh.header.vo.asset.DeviceItemVo;
import com.gcloud.mesh.header.vo.asset.NodeItemVo;
import com.gcloud.mesh.header.vo.asset.SwitcherItemVo;
import com.gcloud.mesh.header.vo.dcs.AppItemVo;
import com.gcloud.mesh.monitor.dao.StatisticsDao;
import com.gcloud.mesh.monitor.entity.StatisticsEntity;
import com.gcloud.mesh.monitor.service.StatisticsCheatService;
import com.gcloud.mesh.redis.MockRedis;

@Component
public class StatisticsTimer {

	@Autowired
	IAssetService assetService;

	@Autowired
	private SysDictMapper sysDictMapper;

	@Autowired
	ICloudResourceService cloudResourceService;

	@Autowired
	AppService appService;
	
	@Autowired
	StatisticsDao statisticsDao;
	
	@Autowired
	private StatisticsCheatService statisticsCheatService;

	@Autowired
	private MockRedis<String> redis;

	@Scheduled(fixedDelay = 1000 * 60 * 5)
	public void work() {

		// 遍历所有监控项
		for (MonitorMeter meter : MonitorMeter.values()) {
			if (meter.getMeter().startsWith("host") || meter.getMeter().startsWith("server")) {
				PageResult<NodeItemVo> items = assetService.pageNode(1, 999999, null, null, null);
				for (NodeItemVo item : items.getList()) {
					recover(meter.getMeter(), item.getId());
				}
			} else if (meter.getMeter().startsWith("vm")) {
				PageCloudResourceMsg msg = new PageCloudResourceMsg();
				msg.setPageNo(1);
				msg.setPageSize(999999);
				msg.setType(0);
				PageResult<CloudResourceItemVo> items = cloudResourceService.page(msg);
				for (CloudResourceItemVo item : items.getList()) {
					recover(meter.getMeter(), item.getId());
				}
			} else if (meter.getMeter().startsWith("container")) {
				PageAppMsg msg = new PageAppMsg();
				msg.setPageNo(1);
				msg.setPageSize(999999);
				PageResult<AppItemVo> items = appService.page(msg);
				for (AppItemVo item : items.getList()) {
					recover(meter.getMeter(), item.getId());
				}
			} else if (meter.getMeter().startsWith("k8s")) {
				PageCloudResourceMsg msgC = new PageCloudResourceMsg();
				msgC.setPageNo(1);
				msgC.setPageSize(999999);
				msgC.setType(1);
				PageResult<CloudResourceItemVo> itemsC = cloudResourceService.page(msgC);
				for (CloudResourceItemVo item : itemsC.getList()) {
					double value = recover(meter.getMeter(), item.getId());
				}
			} else if (meter.getMeter().startsWith("switcher")) {
				PageResult<SwitcherItemVo> items = assetService.pageSwitcher(1, 999999, null, null);
				for (SwitcherItemVo item : items.getList()) {
					double value = recover(meter.getMeter(), item.getId());
					StatisticsEntity entity = new StatisticsEntity();
					entity.setId(UUID.randomUUID().toString());
					entity.setMeter(meter.getMeter());
					entity.setResourceId(item.getId());
					entity.setTimestamp(new Date());
					entity.setValue(value);
					statisticsDao.save(entity);
				}
			//动环数据id变成为数据中心id
			} else if (meter.getMeter().contains("ups")) {
				PageResult<DeviceItemVo> items = assetService.pageDevice(1, 999999, 2, null, null);
				for (DeviceItemVo item : items.getList()) {
					double value = recover(meter.getMeter(), item.getId());
					StatisticsEntity entity = new StatisticsEntity();
					entity.setId(UUID.randomUUID().toString());
					entity.setMeter(meter.getMeter());
					entity.setResourceId(item.getId());
					entity.setTimestamp(new Date());
					entity.setValue(value);
					statisticsDao.save(entity);
				}
			} else if (meter.getMeter().contains("air")) {
				PageResult<DeviceItemVo> items = assetService.pageDevice(1, 999999, 1, null, null);
				for (DeviceItemVo item : items.getList()) {
					double value = recover(meter.getMeter(), item.getId());
					StatisticsEntity entity = new StatisticsEntity();
					entity.setId(UUID.randomUUID().toString());
					entity.setMeter(meter.getMeter());
					entity.setResourceId(item.getId());
					entity.setTimestamp(new Date());
					entity.setValue(value);
					statisticsDao.save(entity);
				}
			} else if (meter.getMeter().contains("distribution_box")) {
				PageResult<DeviceItemVo> items = assetService.pageDevice(1, 999999, 8, null, null);
				for (DeviceItemVo item : items.getList()) {
					double value = recover(meter.getMeter(), item.getId());
					StatisticsEntity entity = new StatisticsEntity();
					entity.setId(UUID.randomUUID().toString());
					entity.setMeter(meter.getMeter());
					entity.setResourceId(item.getId());
					entity.setTimestamp(new Date());
					entity.setValue(value);
					statisticsDao.save(entity);
				}

			} else if (meter.getMeter().startsWith("datacenter")) {
				List<DatacenterItemVo> items = assetService.listDatacenter(new ListDatacenterMsg());
				for (DatacenterItemVo item : items) {
					double value = recover(meter.getMeter(), item.getId());
					StatisticsEntity entity = new StatisticsEntity();
					entity.setId(UUID.randomUUID().toString());
					entity.setMeter(meter.getMeter());
					entity.setResourceId(item.getId());
					entity.setTimestamp(new Date());
					entity.setValue(value);
					statisticsDao.save(entity);
				}

			} else if (meter.getMeter().startsWith("cost")) {
				List<DatacenterItemVo> items = assetService.listDatacenter(new ListDatacenterMsg());
				for (DatacenterItemVo item : items) {
					double value = recover(meter.getMeter(), item.getId());
				}
			}
		}

	}

	private float random() {
		SecureRandom random = new SecureRandom();
		int value = random.nextInt(5) + 98;
		float res = (float) (value * 0.01);

		int type = 0;
		List<DictModel> dicts = sysDictMapper.queryDictItemsByCode(DictCode.MONITOR_STATISTICS_CONFIG.getCode());
		if (dicts != null) {
			for (DictModel dict : dicts) {
				type = Integer.parseInt(dict.getValue());
			}
		}

		if (type == 1) {
			value = random.nextInt(10) + 5;
			res = (float) (value * 0.1);
		} else if (type == 2) {
			res = 0.01f;
		}

		return res;
	}

	private double recover(String meter, String resourceId) {
		String value = redis.getMonitorData(meter, resourceId);
		if (value == null || value.equals("0.0")) {
			value = MonitorMeter.getByMeter(meter).getValue();
		}
		Double dou = Double.parseDouble(value) * random();
		BigDecimal b = new BigDecimal(dou);
		double d = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();

		int type = 3;
		List<DictModel> dicts = sysDictMapper.queryDictItemsByCode(DictCode.MONITOR_TYPE_CONFIG.getCode());
		if (dicts != null) {
			for (DictModel dict : dicts) {
				type = Integer.parseInt(dict.getValue());
			}
		}

		if (type == 0) {
			if (meter.equals("container.cpu_util")) {
				if (d < 70) {
					d = d + 30;
				}
			}
			if (meter.equals("container.fs_reads_rate")) {
				if (d > 100 * 1024) {
					d = d - 100 * 1024;
				}
			}
		} else if (type == 1) {
			if (meter.equals("container.cpu_util")) {
				if (d > 50) {
					d = d - 50;
				}
			}
			if (meter.equals("container.fs_writes_rate")) {
				d = d + 100 * 1024;
			}
		} else if (type == 2) {
			if (meter.equals("container.cpu_util")) {
				if (d < 70) {
					d = d + 30;
				}
			}
			if (meter.equals("container.fs_reads_rate")) {
				d = d + 200 * 1024;
			}
		}

		if(statisticsCheatService.overload(meter, d)){
			d = statisticsCheatService.clearAndInitData(meter, resourceId);
		}
		
		redis.setMonitorData(meter, resourceId, d + "");
		
		return d;
	}
}
